#include "gtest/gtest.h"

#include <container/spw_list.h>
#include <type_traits>
#include <spw_move_in.h>
#include <spw_array.h>

using namespace spwstd;

TEST(list_test, ctor)
{
    {
        List<int> l;
        EXPECT_EQ(l.Size(), 0u);
    }
    {
        List<int> l(3, 6);
        EXPECT_EQ(l.Size(), 3u);
        EXPECT_EQ(l.Front(), 6);
    }
    {
        List<int> l(3, 6);
        List<int> l2(l);
        EXPECT_EQ(l.Size(), 3u);
        EXPECT_EQ(l.Front(), 6);
    }
    {
        List<int> l(3, 6);
        List<int> l2(spwuti::move(l));
        EXPECT_EQ(l2.Size(), 3u);
        EXPECT_EQ(l2.Front(), 6);
        EXPECT_TRUE(l.Empty());
    }
    {
        List<int> l{1,2,3};
        EXPECT_EQ(l.Size(), 3u);
        EXPECT_EQ(l.Front(), 1);
        EXPECT_EQ(l.Back(), 3);
    }
    {
        spwarray::Array<int, 3> arr{1,2,3};
        List<int> l2(arr.Begin(), arr.End());
        EXPECT_EQ(l2.Size(), 3u);
        EXPECT_EQ(l2.Front(), 1);
        EXPECT_EQ(l2.Back(), 3);
    }
}

TEST(list_test, modify_test)
{
    // PushBack
    {
        List<int> l;
        l.PushBack(1);
        EXPECT_EQ(l.Size(), 1u);
        EXPECT_EQ(l.Front(), 1);
        EXPECT_EQ(l.Back(), 1);
    }
    // pushfront
    {
        List<int> l(3);
        l.PushFront(3);
        EXPECT_EQ(l.Size(), 4u);
        EXPECT_EQ(l.Front(), 3);
    }
    // popfront
    {
        List<int> l{1,2,3};
        l.PopFront();
        EXPECT_EQ(l.Size(), 2u);
        EXPECT_EQ(l.Front(), 2);
    }
    // popback
    {
        List<int> l{1,2,3};
        l.PopBack();
        EXPECT_EQ(l.Size(), 2u);
        EXPECT_EQ(l.Back(), 2);
    }
    //emplace
    {
        List<int> l{1,2};
        l.Emplace(l.Begin(), 3);
        EXPECT_EQ(l.Size(), 3u);
        EXPECT_EQ(l.Front(), 3);
    }
    //erase
    {
        List<int> l{1,2};
        l.Erase(l.Begin());
        EXPECT_EQ(l.Size(), 1u);
        EXPECT_EQ(l.Front(), 2);
        EXPECT_EQ(l.Back(), 2);
    }
    //clear
    {
        List<int> l{1,2,3};
        l.Clear();
        EXPECT_TRUE(l.Empty());
    }
    //resize
    {
        List<int> l1{1,2,3};
        List<int> l2;
        l2.Resize(3,3);
        EXPECT_EQ(l2.Size(), 3u);
        EXPECT_EQ(l2.Front(), 3);
        l1.Resize(2, 10);
        EXPECT_EQ(l1.Size(), 2u);
        EXPECT_EQ(l1.Front(), 1);
    }
}
